﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGIS.Model;
using System.IO;
using System.Diagnostics;

namespace FDS_model
{
    class Program
    {
        static ModelServiceContext msc;

        static void sampleModel(string[] args)
        {
            ModelServiceContext msc = new ModelServiceContext();
            ModelDataHandler mdh = new ModelDataHandler(msc);

            if (args.Length < 3) return;

            Guid pInstanceID = msc.onInitialize(args[0], args[1], args[2]);
            if (pInstanceID == Guid.Empty)
                Console.WriteLine("Init Failed");

            msc.onEnterState("RUNSTATE");

            msc.onFireEvent("RUNSTATE", "LOADDATASET");

            msc.onRequestData("RUNSTATE", "LOADDATASET");
            string fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            string dir_work = msc.getCurrentDataDirectory();
            string fds_des = dir_work + "Run.fds";
            File.Copy(fds_file, fds_des);

            msc.onFireEvent("RUNSTATE", "RETURNDATASET");

            ////////////////////////////////
            //程序总目录
            string strPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);

            dir_work = msc.getCurrentDataDirectory();

            string fds5_pro = strPath + "\\fds5.exe";

            FileStream fs = new FileStream(fds_des, FileMode.Open);
            StreamReader sr = new StreamReader(fs);

            string line = sr.ReadLine();
            string resultname = "";

            while (line != null)
            {
                if (line.StartsWith("&HEAD"))
                {
                    line = line.Substring(line.IndexOf("CHID='"));
                    resultname = line.Substring(0, line.IndexOf("'"));
                    break;
                }
                line = sr.ReadLine();
            }

            sr.Close();
            fs.Close();

            msc.setProcessParam("TestValue1", 3);

            Process process1 = new Process();
            process1.StartInfo.FileName = fds5_pro;
            process1.StartInfo.Arguments = fds_des;
            process1.StartInfo.WorkingDirectory = dir_work;
            process1.Start();
            process1.WaitForExit();

            ////////////////////////////////

            msc.setResponseDataFlag(ERequestResponseDataFlag.ERDF_OK);
            msc.setResponseDataMIME(ERequestResponseDataMIME.ERDM_ZIP_FILE);
            string[] file_list = Directory.GetFiles(dir_work);
            mdh.connectDataMappingMethod("");
            mdh.conductFileMapping("FDS_out.zip", file_list.ToList(), file_list.Length);
            msc.setResponseDataBody(dir_work + "FDS_out.zip");
            msc.onResponseData("RUNSTATE", "RETURNDATASET");

            msc.onLeaveState("RUNSTATE");

            msc.onFinalize();
        }

        static void AdvancedModel_1_0(string[] args)
        {
            ModelServiceContext msc = new ModelServiceContext();
            ModelDataHandler mdh = new ModelDataHandler(msc);

            if (args.Length < 3) return;

            Guid pInstanceID = msc.onInitialize(args[0], args[1], args[2]);
            if (pInstanceID == Guid.Empty)
                Console.WriteLine("Init Failed");

            string chid = "OGMS_RUN";

            msc.setProcessParam("TestValue1", 1);

            string fds_file_stream = "&HEAD CHID='" + chid + "',TITLE='Running in OGMS'/\n";

            msc.onEnterState("LOADDATA");

            //! Load MESH Data
            msc.onFireEvent("LOADDATA", "LOADMESHDATA");

            string insDir = msc.getModelInstanceDirectory();

            msc.setProcessParam("TestValue1", 2);

            msc.onRequestData("LOADDATA", "LOADMESHDATA");
            string mesh_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    mesh_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            FileStream fs = new FileStream(mesh_fds_file, FileMode.Open);
            StreamReader sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            msc.setProcessParam("TestValue1", 3);

            //! Load TIME Data
            msc.onFireEvent("LOADDATA", "LOADTIMEDATA");

            msc.onRequestData("LOADDATA", "LOADTIMEDATA");
            string time_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    time_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(time_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");
            
            sr.Close();
            fs.Close();

            msc.setProcessParam("TestValue1", 4);

            //! Load TIME Data
            msc.onFireEvent("LOADDATA", "LOADREACDATA");

            msc.onRequestData("LOADDATA", "LOADREACDATA");
            string reac_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    reac_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            msc.setProcessParam("TestValue1", 5);

            fs = new FileStream(reac_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            //! Load MATL Data
            msc.onFireEvent("LOADDATA", "LOADMATLDATA");

            msc.onRequestData("LOADDATA", "LOADMATLDATA");
            string matl_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    matl_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(matl_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");
            
            sr.Close();
            fs.Close();

            //! Load SURF Data
            msc.onFireEvent("LOADDATA", "LOADSURFDATA");

            msc.onRequestData("LOADDATA", "LOADSURFDATA");
            string surf_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    surf_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(surf_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");
            
            sr.Close();
            fs.Close();

            //! Load OBJ Data
            msc.onFireEvent("LOADDATA", "LOADOBJDATA");

            msc.onRequestData("LOADDATA", "LOADOBJDATA");
            string obj_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    obj_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(obj_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            fds_file_stream += "&TAIL/";

            string fds_file = msc.getCurrentDataDirectory() + "OGMS_RUN.fds";
            fs = new FileStream(fds_file, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            sw.Write(fds_file_stream);

            sw.Close();
            fs.Close();

            msc.onLeaveState("LOADDATA");

            //! Start to run
            msc.onEnterState("RUNANDRETURNDATA");

            msc.onFireEvent("RUNANDRETURNDATA", "RETURNOUTDATA");

            string strPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
            string fds5_pro = strPath + "\\fds5.exe";

            string returnDsDir = msc.getCurrentDataDirectory();

            Process process1 = new Process();
            process1.StartInfo.FileName = fds5_pro;
            process1.StartInfo.Arguments = " \"" + fds_file + "\"";
            process1.StartInfo.WorkingDirectory = returnDsDir;
            process1.Start();
            process1.WaitForExit();

            string[] list_files = Directory.GetFiles(returnDsDir);

            for (int i = 0; i < list_files.Length; i++)
            {
                if (System.IO.Path.GetFileName(list_files[i]) == (chid + ".out"))
                {
                    msc.setResponseDataFlag(ERequestResponseDataFlag.ERDF_OK);
                    msc.setResponseDataMIME(ERequestResponseDataMIME.ERDM_RAW_FILE);
                    msc.setResponseDataBody(list_files[i]);
                    msc.onResponseData("RUNANDRETURNDATA", "RETURNOUTDATA");
                    break;
                }
            }

            for (int i = 0; i < list_files.Length; i++)
            {
                if (System.IO.Path.GetFileName(list_files[i]) == (chid + "_hrr.csv"))
                {
                    msc.onFireEvent("RUNANDRETURNDATA", "RETURNHRRSTATISTIC");
                    msc.setResponseDataFlag(ERequestResponseDataFlag.ERDF_OK);
                    msc.setResponseDataMIME(ERequestResponseDataMIME.ERDM_RAW_FILE);
                    msc.setResponseDataBody(list_files[i]);
                    msc.onResponseData("RUNANDRETURNDATA", "RETURNHRRSTATISTIC");
                    break;
                }
            }

            msc.onFireEvent("RUNANDRETURNDATA", "RETURNVITUALIZATIONDATASET");
            string visdir = msc.getCurrentDataDirectory();
            msc.setResponseDataFlag(ERequestResponseDataFlag.ERDF_OK);
            msc.setResponseDataMIME(ERequestResponseDataMIME.ERDM_ZIP_FILE);
            mdh.connectDataMappingMethod("");
            mdh.conductFileMapping("FDS_Vistualization.zip", list_files.ToList(), list_files.Length);
            msc.setResponseDataBody(visdir + "FDS_Vistualization.zip");
            msc.onResponseData("RUNANDRETURNDATA", "RETURNVITUALIZATIONDATASET");

            msc.onLeaveState("RUNANDRETURNDATA");

            msc.onFinalize();
        }

        static void AdvancedModel_2_0(string[] args)
        {
            msc = new ModelServiceContext();
            ModelDataHandler mdh = new ModelDataHandler(msc);

            if (args.Length < 3) return;

            Guid pInstanceID = msc.onInitialize(args[0], args[1], args[2]);
            if (pInstanceID == Guid.Empty)
                Console.WriteLine("Init Failed");

            string chid = "OGMS_RUN";

            string fds_file_stream = "&HEAD CHID='" + chid + "',TITLE='Running in OGMS'/\n";

            msc.onEnterState("LOADDATA");

            //! Load MESH Data
            msc.onFireEvent("LOADDATA", "LOADMESHDATA");

            msc.onRequestData("LOADDATA", "LOADMESHDATA");
            string mesh_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    mesh_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            FileStream fs = new FileStream(mesh_fds_file, FileMode.Open);
            StreamReader sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            //! Load TIME Parameter
            string stime = msc.getControlParam("Time");
            stime = "&TIME T_END=" + stime + "/\n";

            fds_file_stream += stime;

            //! Load TIME Data
            msc.onFireEvent("LOADDATA", "LOADREACDATA");

            msc.onRequestData("LOADDATA", "LOADREACDATA");
            string reac_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    reac_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(reac_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            //! Load MATL Data
            msc.onFireEvent("LOADDATA", "LOADMATLDATA");

            msc.onRequestData("LOADDATA", "LOADMATLDATA");
            string matl_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    matl_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(matl_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            //! Load SURF Data
            msc.onFireEvent("LOADDATA", "LOADSURFDATA");

            msc.onRequestData("LOADDATA", "LOADSURFDATA");
            string surf_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    surf_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(surf_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            //! Load OBJ Data
            msc.onFireEvent("LOADDATA", "LOADOBJDATA");

            msc.onRequestData("LOADDATA", "LOADOBJDATA");
            string obj_fds_file = "";
            if (msc.getRequestDataFlag() == ERequestResponseDataFlag.ERDF_OK)
            {
                if (msc.getRequestDataMIME() == ERequestResponseDataMIME.ERDM_RAW_FILE)
                {
                    obj_fds_file = msc.getRequestDataBody();
                }
            }
            else
            {
                msc.onFinalize();
            }

            fs = new FileStream(obj_fds_file, FileMode.Open);
            sr = new StreamReader(fs);

            fds_file_stream += (sr.ReadToEnd() + "\n");

            sr.Close();
            fs.Close();

            fds_file_stream += "&TAIL/";

            string fds_file = msc.getCurrentDataDirectory() + "OGMS_RUN.fds";
            fs = new FileStream(fds_file, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            sw.Write(fds_file_stream);

            sw.Close();
            fs.Close();

            msc.onLeaveState("LOADDATA");

            //! Start to run
            msc.onEnterState("RUNANDRETURNDATA");

            msc.onFireEvent("RUNANDRETURNDATA", "RETURNOUTDATA");

            string strPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
            string fds5_pro = strPath + "\\fds5.exe";

            string returnDsDir = msc.getCurrentDataDirectory();

            Process process1 = new Process();
            process1.StartInfo.FileName = fds5_pro;
            process1.StartInfo.Arguments = " \"" + fds_file + "\"";
            process1.StartInfo.WorkingDirectory = returnDsDir;
            process1.StartInfo.UseShellExecute = false;
            process1.StartInfo.CreateNoWindow = false;
            process1.StartInfo.RedirectStandardOutput = false;
            process1.Start();
            process1.WaitForExit();

            string[] list_files = Directory.GetFiles(returnDsDir);

            for (int i = 0; i < list_files.Length; i++)
            {
                if (System.IO.Path.GetFileName(list_files[i]) == (chid + ".out"))
                {
                    msc.setResponseDataFlag(ERequestResponseDataFlag.ERDF_OK);
                    msc.setResponseDataMIME(ERequestResponseDataMIME.ERDM_RAW_FILE);
                    msc.setResponseDataBody(list_files[i]);
                    msc.onResponseData("RUNANDRETURNDATA", "RETURNOUTDATA");
                    break;
                }
            }

            for (int i = 0; i < list_files.Length; i++)
            {
                if (System.IO.Path.GetFileName(list_files[i]) == (chid + "_hrr.csv"))
                {
                    msc.onFireEvent("RUNANDRETURNDATA", "RETURNHRRSTATISTIC");
                    msc.setResponseDataFlag(ERequestResponseDataFlag.ERDF_OK);
                    msc.setResponseDataMIME(ERequestResponseDataMIME.ERDM_RAW_FILE);
                    msc.setResponseDataBody(list_files[i]);
                    msc.onResponseData("RUNANDRETURNDATA", "RETURNHRRSTATISTIC");
                    break;
                }
            }

            msc.onFireEvent("RUNANDRETURNDATA", "RETURNVITUALIZATIONDATASET");
            string visdir = msc.getCurrentDataDirectory();
            msc.setResponseDataFlag(ERequestResponseDataFlag.ERDF_OK);
            msc.setResponseDataMIME(ERequestResponseDataMIME.ERDM_ZIP_FILE);
            mdh.connectDataMappingMethod("");
            mdh.conductFileMapping("FDS_Vistualization.zip", list_files.ToList(), list_files.Length);
            msc.setResponseDataBody(visdir + "FDS_Vistualization.zip");
            msc.onResponseData("RUNANDRETURNDATA", "RETURNVITUALIZATIONDATASET");

            msc.onLeaveState("RUNANDRETURNDATA");

            msc.onFinalize();
        }

        public static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (String.IsNullOrEmpty(e.Data) == false)
            {
                if (e.Data.StartsWith("Time Step"))
                {
                    string[] strArr = e.Data.Split(',');
                    string sstep = strArr[0].Substring(strArr[0].IndexOf(':'));
                    int step = Convert.ToInt32(sstep);
                    msc.setProcessParam("Step", step.ToString());

                    string stime = strArr[1].Substring(strArr[1].IndexOf(':'));
                    stime = stime.Substring(0, stime.IndexOf('s'));
                    msc.setProcessParam("SimuTime", step.ToString());
                }
            }
        }

        public static void process1_Exited(object sender, EventArgs e) 
        {
            
        }

        static void Main(string[] args)
        {
            sampleModel(args);

            //AdvancedModel_1_0(args);

            //AdvancedModel_2_0(args);
        }
    }
}
